package com.bst.bsj.biz.impl;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.SocketAddress;
import java.net.UnknownHostException;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.List;

import javax.net.SocketFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;

import org.apache.commons.httpclient.ConnectTimeoutException;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.NameValuePair;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.httpclient.params.HttpConnectionParams;
import org.apache.commons.httpclient.params.HttpMethodParams;
import org.apache.commons.httpclient.protocol.Protocol;
import org.apache.commons.httpclient.protocol.SecureProtocolSocketFactory;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.stereotype.Service;

import com.bst.bsj.biz.HttpService;
import com.bst.bsj.common.pojo.HttpParams;
import com.bst.bsj.portal.enums.EncryptTypeStatusEnum;
import com.homewaimai.common.lang.MD5Util;
import com.homewaimai.common.lang.Result;
import com.homewaimai.common.lang.ResultSupport;
import com.homewaimai.common.lang.StringUtil;
@Service("httpService")
public class HttpServiceImpl implements HttpService {
    private static final Log logger = LogFactory.getLog(HttpServiceImpl.class);
    private static HttpClient httpClient = null;
    //注册https 验证
    private static   SecureProtocolSocketFactory  mySecureProtocolSocketFactory= new  SecureProtocolSocketFactory() {
         private SSLContext sslcontext = null;
         private SSLContext createSSLContext()
         {
             SSLContext sslcontext = null;
             try
             {
                 sslcontext = SSLContext.getInstance("SSL");
                 sslcontext.init(null, new TrustManager[] { new X509TrustManager(){

                     public void checkClientTrusted(X509Certificate[] chain, String authType)
                             throws CertificateException {
                     }
              
                     public void checkServerTrusted(X509Certificate[] chain, String authType)
                             throws CertificateException {
                     }
              
                     public X509Certificate[] getAcceptedIssuers(){
                         return new X509Certificate[]{};
                     }
                     
                 } }, new java.security.SecureRandom());
             }
             catch (NoSuchAlgorithmException e)
             {
                 logger.error(e);
             }
             catch (KeyManagementException e)
             {
                 logger.error(e);
             }
             return sslcontext;
         }
         private SSLContext getSSLContext()
         {
             if (this.sslcontext == null)
             {
                 this.sslcontext = createSSLContext();
             }
             return this.sslcontext;
         }
      
         public Socket createSocket(Socket socket, String host, int port,
                 boolean autoClose) throws IOException, UnknownHostException
         {
             return getSSLContext().getSocketFactory().createSocket(socket, host,
                     port, autoClose);
         }
      
         public Socket createSocket(String host, int port) throws IOException,
                 UnknownHostException
         {
             return getSSLContext().getSocketFactory().createSocket(host, port);
         }
      
         public Socket createSocket(String host, int port, InetAddress clientHost,
                 int clientPort) throws IOException, UnknownHostException
         {
             return getSSLContext().getSocketFactory().createSocket(host, port,
                     clientHost, clientPort);
         }
         public Socket createSocket(String host, int port, InetAddress localAddress,
                 int localPort, HttpConnectionParams params) throws IOException,
                 UnknownHostException, ConnectTimeoutException
         {
             if (params == null)
             {
                 throw new IllegalArgumentException("Parameters may not be null");
             }
             int timeout = params.getConnectionTimeout();
             SocketFactory socketfactory = getSSLContext().getSocketFactory();
             if (timeout == 0)
             {
                 return socketfactory.createSocket(host, port, localAddress,
                         localPort);
             }
             else
             {
                 Socket socket = socketfactory.createSocket();
                 SocketAddress localaddr = new InetSocketAddress(localAddress,
                         localPort);
                 SocketAddress remoteaddr = new InetSocketAddress(host, port);
                 socket.bind(localaddr);
                 socket.connect(remoteaddr, timeout);
                 return socket;
             }
         }
    };
    
    static{
        Protocol myhttps = new Protocol("https", mySecureProtocolSocketFactory, 443);
        Protocol.registerProtocol("https", myhttps);
    }
    
     
 
    @Override
    public Result httpGet(String url) {
       return  httpGet(url,"UTF-8");
    }

    @Override
    public Result httpGet(String url, List<HttpParams> httpParams) {
       return httpGet(url,httpParams,"UTF-8");
        
        
    }
    //数据加密处理
    private String encrypt(HttpParams hp) {
        if(EncryptTypeStatusEnum.MD5.getCode().equalsIgnoreCase(hp.getEncryptType())){
            try {
                return MD5Util.getMD5(hp.getValue());
            } catch (Exception e) {
                logger.error(e);
            }
            return null;
        }else{
            return hp.getValue();
        }
        
    }

    @Override
    public Result httpPost(String url, List<HttpParams> httpParams) {
        return httpPost(url,  httpParams,"UTF-8");
       
    }

    @Override
    public Result httpGet(String url, String charset) {
        Result r =new ResultSupport(false);
        String result = null;
        InputStream in=null;
        BufferedReader buffer = null;
        try {
            HttpClient httpClient = new HttpClient();
            GetMethod getMethod = new GetMethod(url);
            httpClient.getParams().setParameter(HttpMethodParams.HTTP_CONTENT_CHARSET, charset);
            httpClient.getHttpConnectionManager().getParams().setSoTimeout(HttpService.TIME_OUT); 
         //   getMethod.getParams().setParameter("http.method.retry-handler", new DefaultHttpMethodRetryHandler());
            int statusCode = httpClient.executeMethod(getMethod);
            if (statusCode == 200) {
                String  cs=getMethod.getRequestCharSet();
                StringBuffer temp = new StringBuffer();
                 in = getMethod.getResponseBodyAsStream();
                 buffer = new BufferedReader(new InputStreamReader(in, cs));
                for (String tempstr = ""; (tempstr = buffer.readLine()) != null;)
                    temp = temp.append(tempstr);
                buffer.close();
                in.close();
                result = temp.toString().trim();
                r.setDefaultModel("content", result);
                r.setDefaultModel("charset", cs);
                r.setSuccess(true);
            }else{
                r.setDefaultModel("数据返回错误，返回码："+statusCode);
            }
        } catch (Exception e) {
            r.setDefaultModel("连接异常");
        }finally{
            if(in!=null){
                try {
                    in.close();
                } catch (IOException e) {
                }
            }
            if(buffer!=null){
                try {
                    buffer.close();
                } catch (IOException e) {
                }
            }
        }
        return r;
    }

    @Override
    public Result httpGet(String url, List<HttpParams> httpParams,
            String charset) {
        
        if(httpParams==null){
            return httpGet(url);
        }
        String surl=null;
        if(url.indexOf("?")==-1){
            surl=url+"?";
        }else{
            surl=url;
        }
        String hparas=null;
        for(HttpParams hp:httpParams){
            hparas = encrypt(hp);
            surl += "&"+hp.getKey()+"="+hparas;
        }
        return httpGet(surl ,charset);

    }

    @Override
    public Result httpPost(String url, List<HttpParams> httpParams,
            String charset) {
       return httpPost( url, httpParams,
   			null,  charset);
    }

	@Override
	public Result httpPost(String url, List<HttpParams> httpParams,
			String contentType, String charset) {
		 Result r=new ResultSupport(false);
	        String result = null;
	        InputStream in=null;
	        BufferedReader buffer = null;
	        try {
	            HttpClient httpClient = new HttpClient();
	            httpClient.getParams().setParameter(HttpMethodParams.HTTP_CONTENT_CHARSET, charset);
	            httpClient.getHttpConnectionManager().getParams().setSoTimeout(HttpService.TIME_OUT); 
	            PostMethod postMethod = new PostMethod(url);
	            String ct = "application/x-www-form-urlencoded";
	            if(StringUtil.isNotBlank(contentType)){
	            	ct = contentType;
	            }
	            postMethod.setRequestHeader("Content-Type",ct);
	            String hparas = null;
	            List<NameValuePair> nvpList=new ArrayList<NameValuePair>();
	            for(HttpParams hp:httpParams){
	                NameValuePair pb=new NameValuePair();
	                hparas = encrypt(hp);
	                pb.setName(hp.getKey());   
	                pb.setValue(hparas);
	                nvpList.add(pb);
	            }
	            postMethod.setRequestBody((NameValuePair[])(nvpList.toArray(new NameValuePair[nvpList.size()])));
	           
	           //postMethod.getParams().setParameter("http.method.retry-handler", new DefaultHttpMethodRetryHandler());
	            int statusCode = httpClient.executeMethod(postMethod);
	            
	            if (statusCode == 200) {
	                String  cs=postMethod.getRequestCharSet();
	                StringBuffer temp = new StringBuffer();
	                 in = postMethod.getResponseBodyAsStream();
	                 buffer = new BufferedReader(new InputStreamReader(in, cs));
	                for (String tempstr = ""; (tempstr = buffer.readLine()) != null;)
	                    temp = temp.append(tempstr);
	                buffer.close();
	                in.close();
	                result = temp.toString().trim();
	                r.setDefaultModel("content", result);
	                r.setDefaultModel("charset", cs);
	                r.setSuccess(true);
	            }else{
	                r.setDefaultModel("数据返回错误，返回码："+statusCode);
	            }
	           
	        } catch (Exception e) {
	            e.printStackTrace();
	           r.setDefaultModel("连接异常");
	        }finally{
	            if(in!=null){
	                try {
	                    in.close();
	                } catch (IOException e) {
	                }
	            }
	            if(buffer!=null){
	                try {
	                    buffer.close();
	                } catch (IOException e) {
	                }
	            }
	        }
	        return r;
	}
}
